home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / cmp.c < prev    next >
Text File  |  1985-06-03  |  7KB  |  292 lines

  1. /* : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
  2.     Program to compare (byte for byte)
  3.     two files and print differences
  4.  
  5.     H.Moran        10/27/79
  6.     slight mod    2/13/80
  7.    : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : */
  8. /*
  9.     Whatever compiler Mr. Morgan uses it is very non-K & R
  10.     or maybe it's Unix V6 rather than V7 or system III or some
  11.     thing like that...So I've taken the liberty of making it
  12.     ci-c86-able and at least as of 3/20/84 this works for
  13.     ascii files
  14.             Matthew Weinstein
  15.  
  16.     Finis.... added binary file option...BEWARE USER
  17.     this will open files as binary .... otherwise use
  18.     the -a flag. --3/21/84
  19.  
  20.             Matthew Weinstein
  21.  
  22. */
  23.  
  24. /* : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :
  25.     Macros for constant definitions
  26.    : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : */
  27. #define TRUE 1
  28. #define FALSE 0
  29. #define EOFF -1        /* end of file marker returned by getc() */
  30. #define NOFILE 0    /* no such file indication given by fopen() */
  31. #include "stdio.h"
  32.  
  33. /*    -------------------------------------------------------
  34.  
  35.     Name:        main(argc,argv)
  36.     Result:        ---
  37.     Errors:        invocation syntax error or no such file
  38.     Globals:    ---
  39.     Macros:        TRUE,FALSE,NOFILE
  40.     Procedures:    fopen(),tolower(),bummer(),htoi(),fcompare()
  41.  
  42.     Action:        Byte by byte compare of 2 files and
  43.             print their differences on console
  44.  
  45.     ------------------------------------------------------- */
  46.  
  47.  
  48. main(argc,argv)
  49.     int argc;
  50.     char *argv[];
  51. {
  52.     FILE *fopen(),*fd1,*fd2;
  53.     int ascii;
  54.     unsigned start_adrs,htoi();
  55.     char mode[3], *ptr, *strcpy();
  56.  
  57.     strcpy(mode,"rb");
  58.     ascii = FALSE;    /* assign the defaults */
  59.     start_adrs = 0;
  60.       while( argc > 3 ) 
  61.      {
  62.         ptr = argv[--argc];
  63.         if( *ptr++ != '-' )
  64.           bummer();
  65.         switch ( tolower(*ptr++) ) 
  66.           {
  67.           case 'a':    ascii = TRUE;
  68.             strcpy(mode,"r");
  69.             break;
  70.  
  71.           case 'b':    start_adrs = htoi(ptr);
  72.             break;
  73.  
  74.           default:    puts("Unrecognized option. Aborted\n\n");
  75.             bummer();
  76.           }    /* end switch */
  77.         }    /* end while */
  78.     if( argc < 3 || argc > 5 )
  79.       bummer();
  80.     else if( (fd1 = fopen(argv[1],mode)) == NOFILE )
  81.       printf("No such file %s\n",argv[1]);
  82.     else if( (fd2  = fopen(argv[2],mode)) == NOFILE)
  83.       printf("No such file %s\n",argv[2]);
  84.     else  fcompare(fd1,fd2,start_adrs,ascii);
  85.     exit();
  86.     }
  87.  
  88.  
  89. /*    -------------------------------------------------------
  90.  
  91.     Name:        fcompare(mfile,cfile,adrs,ascii)
  92.     Result:        ---
  93.     Errors:        ---
  94.     Globals:    ---
  95.     Macros:        EOFF,EOF
  96.     Procedures:    getc(),puts(),strcpy(),printf()
  97.  
  98.     Action:        compare 2 files and print their differences
  99.             on the console
  100.  
  101.     ------------------------------------------------------- */
  102.  
  103.  
  104.  
  105. fcompare(mfile,cfile,adrs,ascii)
  106.     FILE *mfile;        /* the input file buffer */
  107.     FILE *cfile;        /* the output file buffer */
  108.     unsigned adrs;        /* the address of begin of file */
  109.     int ascii;        /* flag of whether these are ascii files */
  110.     {
  111.     int mc,cc;        /* 1 char buffers */
  112.     char erflg;        /* flag that an error has occurred */
  113.     char *xl();        /* function to translate control chars */
  114.     char str1[6],str2[6];    /* temporaries for strings */
  115.     char xlate[10];    /* string used in ascii control char translation */
  116.  
  117.  
  118.     erflg = 0;
  119.     while( ! ( (mc = getc(mfile)) == EOFF || (ascii && mc == EOF)) ) {
  120.       if( (cc =getc(cfile)) == EOFF || ( ascii && cc == EOF )) {
  121.         puts("Checkfile shorter than Master file\n");
  122.         return;
  123.         }
  124.       else if( mc != cc ) {
  125.         if( ! erflg ) {
  126.           erflg = 1;
  127.           puts("\nRelative Master Check");
  128.           puts("\nAddress  File   File   Mismatch");
  129.           puts("\n-------  ----   ----   --------\n");
  130.           }    /* end if */
  131.         if( ascii )    {
  132.           strcpy(str1,xl(mc,xlate)); /* fudge because parameters are */
  133.           strcpy(str2,xl(cc,xlate)); /* evaluated before being passed */
  134.           printf("%4x     %-4s   %-4s   %8b\n",adrs,str1,str2,mc^cc);
  135.           }
  136.         else
  137.           printf("%4x     %2x     %2x     %8b\n",adrs,mc,cc,mc ^ cc);
  138.         }        /* end else if */
  139.       else
  140.         ;
  141.       adrs++;
  142.       }        /* end while */
  143.     if(! ( (cc = getc(cfile)) == EOFF || (ascii && cc == EOF) ) )
  144.       puts("Masterfile shorter than checkfile\n");
  145.     return;
  146.     }        /* end fcompare() */
  147.  
  148. /*    -------------------------------------------------------
  149.  
  150.     Name:        err_exit(msg)
  151.     Result:        ---
  152.     Errors:        ---
  153.     Globals:    ---
  154.     Macros:        ---
  155.     Procedures:    printf(),exit()
  156.  
  157.     Action:        Print a message then exit to CP/M 
  158.  
  159.     ------------------------------------------------------- */
  160.  
  161.  
  162. err_exit(msg)
  163.     char *msg;
  164.     {
  165.     exit(puts(msg));
  166.     }
  167.  
  168. /*    -------------------------------------------------------
  169.  
  170.     Name:        htoi(string)
  171.     Result:        unsigned integer value of ascii hex string
  172.     Errors:        ---
  173.     Globals:    ---
  174.     Macros:        ---
  175.     Procedures:    tolower(),isalpha(),isdigit()
  176.  
  177.     Action:        ---
  178.  
  179.     ------------------------------------------------------- */
  180.  
  181.  
  182. unsigned htoi(string)
  183.     char *string;
  184.     {
  185.     unsigned number;
  186.     char c;
  187.  
  188.     number = 0;
  189.     c = tolower(*string++);
  190.     while( isalpha(c) || isdigit(c) ) {
  191.       if( c > 'f' )
  192.         return number;
  193.       number *= 16;
  194.       if( isdigit(c) )
  195.         number += c -'0';
  196.       else
  197.         number += c - 'a' + 10;
  198.       c = tolower(*string++);
  199.       }
  200.     return number;
  201.     }
  202. /*    -------------------------------------------------------
  203.  
  204.     Name:        bummer()
  205.     Result:        ---
  206.     Errors:        ---
  207.     Globals:    ---
  208.     Macros:        ---
  209.     Procedures:    puts(),exit()
  210.  
  211.     Action:        Print the invocation syntax error message
  212.             and exit to CP/M
  213.  
  214.     ------------------------------------------------------- */
  215.  
  216.  
  217. bummer()
  218.     {
  219.     puts("Correct invocation form is:\n");
  220.     puts(" FILECOMP <master file> <check file> {-a -b<hex-num>}\n\n");
  221.     puts("Where optional arguments are:\n\n");
  222.     puts("-a          => these are ascii files (terminate on 1AH )\n");
  223.     puts("-b<hex-num> => begin of file is address <hex-num> ");
  224.     puts("default is 0\n");
  225.     exit();
  226.     }
  227.  
  228.  
  229. /*    -------------------------------------------------------
  230.  
  231.     Name:        xl(c)
  232.     Result:        pointer to  xlate[]
  233.     Errors:        ---
  234.     Globals:
  235.     Macros:        ---
  236.     Procedures:    strcpy()
  237.  
  238.     Action:        Translate the char argument c into a
  239.             4 char string in  xlate[]
  240.             If c is a printable ascii char its
  241.               translation is itself right blank padded
  242.             Else if c is a standard control char its
  243.               translation is a string identifying that
  244.               control char
  245.             Else its translation is "????"
  246.  
  247.     ------------------------------------------------------- */
  248.  
  249.  
  250. char *xl(c,xlate)
  251.     int c;
  252.     char *xlate;
  253.     {
  254.     if( c > 0x7f || c < 0 )
  255.       strcpy(xlate,"????");
  256.     else if( c == 0x7f )
  257.       strcpy(xlate,"del ");
  258.     else if( c > 0x1f ) {    /* then it is printable */
  259.       xlate[0] = c;
  260.       strcpy(xlate+1,"   ");
  261.       }
  262.     else
  263.       switch (c) {
  264.         case 0x7:    strcpy(xlate,"bel");
  265.             break;
  266.  
  267.         case 0x8:    strcpy(xlate,"bs");
  268.             break;
  269.  
  270.         case 0x9:    strcpy(xlate,"tab");
  271.             break;
  272.  
  273.         case 0xa:    strcpy(xlate,"lf");
  274.             break;
  275.  
  276.         case 0xc:    strcpy(xlate,"ff");
  277.             break;
  278.  
  279.         case 0xd:    strcpy(xlate,"cr");
  280.             break;
  281.  
  282.         case 0x1b:    strcpy(xlate,"esc");
  283.             break;
  284.  
  285.         default:    xlate[0] = '^';        /* show control chars as */
  286.             xlate[1] = c + 0x40;    /* ^ <char> e.g. ^A is */
  287.             xlate[2] = '\0';    /* control A */
  288.             break;
  289.         }
  290.     return xlate;
  291.     }
  292.